package com.zhixing.order.websocket;

import com.zhixing.order.domain.vo.OrderStatusVO;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static com.zhixing.common.constant.Constant.ZHIXING_ORDER_WEBSOCKET;

@Slf4j
@Component
@ServerEndpoint(value = "/ws/order/{orderId}", encoders = {OrderWebSocketEncoder.class})
public class OrderWebSocket {

    private static String instanceId;
    private static RedisTemplate<String, Object> redisTemplate;
    private final static Map<Long, Session> map = new ConcurrentHashMap<>();

    @Autowired
    public void setInstanceId(@Value("${spring.application.instance-id}") String instanceId) {
        OrderWebSocket.instanceId = instanceId;
    }

    @Autowired
    public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
        OrderWebSocket.redisTemplate = redisTemplate;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("orderId") Long orderId) {
        log.info("websocket服务连接，订单websocket连接，订单id：{}", orderId);
        map.put(orderId, session);
        redisTemplate.opsForHash().put(ZHIXING_ORDER_WEBSOCKET, orderId, instanceId);
    }

    @OnClose
    public void onClose(@PathParam("orderId") Long orderId) {
        log.info("websocket服务关闭，订单websocket关闭，订单id：{}", orderId);
        map.remove(orderId);
        redisTemplate.opsForHash().delete(ZHIXING_ORDER_WEBSOCKET, orderId);
    }

    @OnError
    public void onError(@PathParam("orderId") Long orderId, Throwable throwable) {
        log.info("websocket服务连接错误，订单websocket错误，订单id：{}", orderId);
        map.remove(orderId);
        redisTemplate.opsForHash().delete(ZHIXING_ORDER_WEBSOCKET, orderId);
        throwable.printStackTrace();
    }

    public void sendMessage(OrderStatusVO orderStatusVO) {
        String id = (String) redisTemplate.opsForHash().get(ZHIXING_ORDER_WEBSOCKET, orderStatusVO.getOrderId());
        Session session = map.get(orderStatusVO.getOrderId());
        if (id != null && session != null) session.getAsyncRemote().sendObject(orderStatusVO);
    }
}
